<!--
 - MineAdmin is committed to providing solutions for quickly building web applications
 - Please view the LICENSE file that was distributed with this source code,
 - For the full copyright and license information.
 - Thank you very much for using MineAdmin.
 -
 - @Author X.Mo<root@imoi.cn>
 - @Link   https://gitee.com/xmo/mineadmin-vue
-->
<template>
  <a-spin :loading="searchLoading" :tip="options.searchLoadingText" >
    <a-row class="posSearch">
      <a-form
          :model="searchForm"
          layout="inline"
          :label-align="options?.searchLabelAlign"
          ref="searchRef"
          class="form-main"
          :class="{'searchHide': !showSearch && searchColumns.length>5}"
          
          @submit="handlerSearch"
      >
      <a-col :span="21">
      <a-grid :cols="searchColumns.length>5?5:searchColumns.length" :colGap="12" :rowGap="16" :class="[ gridClass, options?.searchCustomClass ]" :collapsed="showSearch">
        <template v-for="(component, index) in searchColumns" :key="index">
          <a-grid-item class="demo-item isShow">
          <a-form-item
              :field="component.dataIndex"
              :label="component.title"
              label-col-flex="auto"
              :label-component="$slots[`${component.dataIndex}-label`] ? 'span':'label'"
              :label-col-style="{ width: component.searchLabelWidth ?? options.searchLabelWidth}"
              :class="component.title.length > 4 ? 'long-search-label':''"
          >
            <slot :name="`${component.dataIndex}`" v-bind="{ searchForm, component }">
              <component :is="getComponentName(component.searchFormType ?? component.formType)" :component="component"/>
            </slot>

            <template #label>
              <slot :name="`${component.dataIndex}-label`" v-bind="{ searchForm, component }">
                {{component.title}}
              </slot>
            </template>
          </a-form-item>
          </a-grid-item>
        </template>
      </a-grid>
      </a-col>
      <a-col :span="3">
    <div class="" v-if="searchColumns.length > 0">
      <a-space >
        <slot name="searchBeforeButtons"/>
        <slot name="searchButtons">
          <a-button type="primary" html-type="submit">
            <template #icon>
              <icon-search/>
            </template>
            {{ options.searchSubmitButtonText }}
          </a-button>
          <a-button @click="resetSearch">
            <template #icon>
              <icon-delete/>
            </template>
            {{ options.searchResetButtonText }}
          </a-button>
        </slot>
        <slot name="searchAfterButtons"/>
      </a-space>
    </div>
      </a-col>
      <a-col v-if="searchColumns.length>5" :span="3" :offset="11">
        <a-link v-if="!showSearch" @click="showSearch=!showSearch" size="small" style="margin-bottom: 10px;">
          {{ !showSearch ? '收起':'' }}
          <template #icon>
            <icon-up v-if="!showSearch" />
          </template>
        </a-link>
      </a-col>
      </a-form>
    </a-row>
  </a-spin>
</template>

<script setup>
import {ref, inject, provide, markRaw, computed} from 'vue'
import MaFormInput from './searchFormItem/form-input.vue'
import MaFormPicker from './searchFormItem/form-picker.vue'
import MaFormSelect from './searchFormItem/form-select.vue'
import MaFormCascader from './searchFormItem/form-cascader.vue'
import MaFormTreeSelect from './searchFormItem/form-tree-select.vue'
import { cloneDeep, isFunction } from "lodash"

const options = inject('options')
const columns = inject('columns')
const requestParams = inject('requestParams')
const isShow = ref(false)
const gridClass = ref(['ma-search-grid', 'w-full', 'grid', 'lg:grid-cols-' + options.searchColNumber ?? 4, 'md:grid-cols-3', 'xl:grid-cols-5'])

const searchLoading = ref(false)
const showSearch = ref(true)
const searchRef = ref(null)
const searchColumns = ref([])

const searchForm = ref({})

const more = () =>{
  isShow.value = isShow.value ? false : true
}

provide('searchForm', searchForm)

const emit = defineEmits(['search'])

const getSearchAllColumns = (cls = []) => {
  let sls = []
  cls.map(item => {
    if (item.children && item.children.length > 0) {
      let tmp = getSearchAllColumns(item.children)
      sls.push(...tmp)
    } else if (item.dataIndex && item.search && item.search === true) {
      sls.push(item)
    }
  })
  return sls
}

const initSearchColumns = () => {
  if (columns.value.length > 0) {
    searchColumns.value = cloneDeep(getSearchAllColumns(columns.value).filter( item => item.search === true && ( options.tabs?.dataIndex != item.dataIndex ) ))
  }
}

const handlerSearch = () => {
  emit('search', searchForm.value)
}

const resetSearch = async () => {
  searchRef.value.resetFields()
  Object.keys(searchForm.value).map(item => {
    let temp = item.match(/^(.+)Min$/)
    if (temp) {
      searchForm.value[temp[1] + 'Min'] = undefined
      searchForm.value[temp[1] + 'Max'] = undefined
    }
  })
  if (options.resetSearch && isFunction(options.resetSearch)) {
    await options.resetSearch(searchForm.value)
  }
  emit('search', searchForm.value)
}

const componentList = ref({
  'MaFormSelect': markRaw(MaFormSelect),
  'MaFormPicker': markRaw(MaFormPicker),
  'MaFormCascader': markRaw(MaFormCascader),
  'MaFormTreeSelect': markRaw(MaFormTreeSelect),
  'MaFormInput': markRaw(MaFormInput),
})

const getComponentName = (formType) => {
  if (['select', 'radio', 'checkbox', 'transfer'].includes(formType)) {
    return componentList.value['MaFormSelect']
  } else if (['date', 'month', 'year', 'week', 'quarter', 'range', 'time'].includes(formType)) {
    return componentList.value['MaFormPicker']
  } else if (formType === 'cascader') {
    return componentList.value['MaFormCascader']
  } else if (formType === 'tree-select') {
    return componentList.value['MaFormTreeSelect']
  } else {
    return componentList.value['MaFormInput']
  }
}

initSearchColumns()

const setSearchHidden = () => showSearch.value = false
const setSearchDisplay = () => showSearch.value = true
const setSearchLoading = () => searchLoading.value = true
const setSearchUnLoading = () => searchLoading.value = false
const getSearchFormRef = () => searchRef.value
const getSearchColumns = () => searchColumns.value

defineExpose({
  initSearchColumns,getSearchFormRef, getSearchColumns, showSearch, resetSearch,
  setSearchHidden, setSearchDisplay, setSearchLoading, setSearchUnLoading
})
</script>

<style scoped lang="less">
:deep(.arco-form-item-label-required-symbol svg) {
  vertical-align: baseline !important;
}
.isShow{
  display:block !important;
}
:deep(.long-search-label .arco-form-item-label-col .arco-form-item-label){
  line-height:normal;
}
.posSearch{
  // padding: 1rem 1rem 0;
   position: absolute;
    left: 0;
    width: 100%;
    top: 0;
    z-index: 800;
    // background: #ffffff;
    // margin: 0.75rem;
    padding: 0.75rem;
}
.form-main{
  height: 55px;
  overflow: hidden;
  padding: 1rem 1rem 0;
  background: #ffffff;
}
.searchHide {
  height: auto;
  box-shadow: 0 10px 10px 10px #ccc;

}


</style>
